package ansible

import (
	"fmt"
	"os"
	"strings"
)

// InventoryBuilder 提供更灵活的 inventory 构建方式
type InventoryBuilder struct {
	groups map[string]*InventoryGroup
}

// InventoryGroup 表示一个主机组
type InventoryGroup struct {
	Name     string
	Hosts    []*Host
	Children []string
	Vars     map[string]string
}

// Host 表示一个主机（增强版）
type Host struct {
	Name     string
	Address  string
	Port     int
	User     string
	Password string
	Vars     map[string]string
}

// NewInventoryBuilder 创建新的 inventory 构建器
func NewInventoryBuilder() *InventoryBuilder {
	return &InventoryBuilder{
		groups: make(map[string]*InventoryGroup),
	}
}

// AddGroup 添加主机组
func (ib *InventoryBuilder) AddGroup(name string) *InventoryBuilder {
	if _, exists := ib.groups[name]; !exists {
		ib.groups[name] = &InventoryGroup{
			Name:     name,
			Hosts:    make([]*Host, 0),
			Children: make([]string, 0),
			Vars:     make(map[string]string),
		}
	}
	return ib
}

// AddHostToGroup 向指定组添加主机
func (ib *InventoryBuilder) AddHostToGroup(groupName string, host *Host) *InventoryBuilder {
	ib.AddGroup(groupName)
	ib.groups[groupName].Hosts = append(ib.groups[groupName].Hosts, host)
	return ib
}

// AddChildGroup 添加子组
func (ib *InventoryBuilder) AddChildGroup(parentGroup, childGroup string) *InventoryBuilder {
	ib.AddGroup(parentGroup)
	ib.AddGroup(childGroup)
	ib.groups[parentGroup].Children = append(ib.groups[parentGroup].Children, childGroup)
	return ib
}

// SetGroupVar 设置组变量
func (ib *InventoryBuilder) SetGroupVar(groupName, key, value string) *InventoryBuilder {
	ib.AddGroup(groupName)
	ib.groups[groupName].Vars[key] = value
	return ib
}

// SetGroupVars 批量设置组变量
func (ib *InventoryBuilder) SetGroupVars(groupName string, vars map[string]string) *InventoryBuilder {
	ib.AddGroup(groupName)
	for k, v := range vars {
		ib.groups[groupName].Vars[k] = v
	}
	return ib
}

// NewHost 创建新主机
func NewHost(name, address string) *Host {
	return &Host{
		Name:     name,
		Address:  address,
		Port:     22,
		User:     "root",
		Vars:     make(map[string]string),
	}
}

// WithPort 设置端口
func (h *Host) WithPort(port int) *Host {
	h.Port = port
	return h
}

// WithUser 设置用户
func (h *Host) WithUser(user string) *Host {
	h.User = user
	return h
}

// WithPassword 设置密码
func (h *Host) WithPassword(password string) *Host {
	h.Password = password
	return h
}

// WithVar 设置主机变量
func (h *Host) WithVar(key, value string) *Host {
	h.Vars[key] = value
	return h
}

// WithVars 批量设置主机变量
func (h *Host) WithVars(vars map[string]string) *Host {
	for k, v := range vars {
		h.Vars[k] = v
	}
	return h
}

// String 返回主机的 inventory 字符串表示
func (h *Host) String() string {
	var parts []string
	
	// 基本连接信息
	parts = append(parts, fmt.Sprintf("ansible_host=%s", h.Address))
	if h.User != "" {
		parts = append(parts, fmt.Sprintf("ansible_user=%s", h.User))
	}
	if h.Port != 22 {
		parts = append(parts, fmt.Sprintf("ansible_port=%d", h.Port))
	}
	if h.Password != "" {
		parts = append(parts, fmt.Sprintf("ansible_password='%s'", h.Password))
	}
	
	// 自定义变量
	for k, v := range h.Vars {
		parts = append(parts, fmt.Sprintf("%s='%s'", k, v))
	}
	
	return fmt.Sprintf("%s    %s", h.Name, strings.Join(parts, "    "))
}

// Build 构建 inventory 字符串
func (ib *InventoryBuilder) Build() string {
	var lines []string
	
	for groupName, group := range ib.groups {
		// 组头
		lines = append(lines, fmt.Sprintf("[%s]", groupName))
		
		// 组内主机
		for _, host := range group.Hosts {
			lines = append(lines, host.String())
		}
		
		// 子组
		if len(group.Children) > 0 {
			lines = append(lines, fmt.Sprintf("[%s:children]", groupName))
			for _, child := range group.Children {
				lines = append(lines, child)
			}
		}
		
		// 组变量
		if len(group.Vars) > 0 {
			lines = append(lines, fmt.Sprintf("[%s:vars]", groupName))
			for k, v := range group.Vars {
				lines = append(lines, fmt.Sprintf("%s=%s", k, v))
			}
		}
		
		lines = append(lines, "") // 空行分隔
	}
	
	return strings.Join(lines, "\n")
}

// SaveToFile 保存到文件
func (ib *InventoryBuilder) SaveToFile(filename string) error {
	content := ib.Build()
	return os.WriteFile(filename, []byte(content), 0644)
}

// ToTempFile 保存到临时文件
func (ib *InventoryBuilder) ToTempFile() (string, error) {
	tempFile, err := os.CreateTemp("", "ansible_inventory_*.ini")
	if err != nil {
		return "", err
	}
	defer tempFile.Close()
	
	content := ib.Build()
	_, err = tempFile.WriteString(content)
	if err != nil {
		os.Remove(tempFile.Name())
		return "", err
	}
	
	return tempFile.Name(), nil
}

// DockerInventoryBuilder 专门用于 Docker 容器的 inventory 构建器
type DockerInventoryBuilder struct {
	*InventoryBuilder
}

// NewDockerInventoryBuilder 创建 Docker inventory 构建器
func NewDockerInventoryBuilder() *DockerInventoryBuilder {
	return &DockerInventoryBuilder{
		InventoryBuilder: NewInventoryBuilder(),
	}
}

// AddDockerContainer 添加 Docker 容器
func (dib *DockerInventoryBuilder) AddDockerContainer(name, containerID string, sshPort int) *DockerInventoryBuilder {
	host := NewHost(name, "localhost").
		WithPort(sshPort).
		WithVar("ansible_connection", "ssh").
		WithVar("container_id", containerID)
	
	dib.AddHostToGroup("docker_containers", host)
	return dib
}

// AddDockerSSHContainer 添加支持 SSH 的 Docker 容器
func (dib *DockerInventoryBuilder) AddDockerSSHContainer(name, user, password string, sshPort int) *DockerInventoryBuilder {
	host := NewHost(name, "localhost").
		WithPort(sshPort).
		WithUser(user).
		WithPassword(password).
		WithVar("ansible_connection", "ssh")
	
	dib.AddHostToGroup("docker_ssh", host)
	return dib
}

// SetDockerDefaults 设置 Docker 相关的默认变量
func (dib *DockerInventoryBuilder) SetDockerDefaults() *DockerInventoryBuilder {
	dib.SetGroupVars("docker_containers", map[string]string{
		"ansible_python_interpreter": "/usr/bin/python3",
		"ansible_ssh_common_args":    "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null",
	})
	
	dib.SetGroupVars("docker_ssh", map[string]string{
		"ansible_python_interpreter": "/usr/bin/python3",
		"ansible_ssh_common_args":    "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null",
	})
	
	return dib
}
